package ro.utcn.oop.mandelbrot.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JToolBar;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import ro.utcn.oop.mandelbrot.model.ImageDefs;
import ro.utcn.oop.mandelbrot.model.ImageService;

/**
 * This is the main screen of the application.
 * 
 */
public class MandelbrotScreen extends JPanel implements ChangeListener {  //cu desenarea si actiunile de zoom si reset
	private static final int MAX_ITERATION = 2000;

	/** Serial version UID for this class. */
	private static final long serialVersionUID = 2368922023654479443L;  //e autogenerata

	/** Zoom action. */
	private Action zoomAction; //actiunile pe care se executa cand dau clic in meniu sau toolbar

	/** Reset action. */
	private Action resetAction;

	/** Exit application action. */
	private Action exitAction;

	/** About action. */
	private Action aboutAction;

	/** The simulation speed slider. */
	private JSlider iterationSlider;

	/** A reference to the mandelbrot panel. */
	private MandelbrotPanel mandelbrotPanel; //unde se deseneaza

	/** A reference to the image service. */
	private ImageService imageService;//pentru a tine imaginile

	/** The simulation speed. */
	private int iterationNumber;//nr de iteratii setat din slider

	/**
	 * The constructor of the MandelbrotScreen class. initializes the screen.
	 */
	public MandelbrotScreen() { //initializez iterationnumber
		super(new BorderLayout());
		iterationNumber = 50*MAX_ITERATION/100; //la 50%
		imageService = ImageService.getInstance();//instantiez imageservice
		createActions();
		createComponents();//instantiaza ce trebuie afisat
	}

	/**
	 * Initializes all the actions.
	 */
	private void createActions() { //instantiaza actiunile care trebuie executate
		zoomAction = new AbstractAction("Zoom") { //instantiez
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;//e generat

			@Override
			public void actionPerformed(ActionEvent arg0) {//metoda ca atunci cand dau clic pe zoomaction...
				mandelbrotPanel.zoom();
			}
		};
		zoomAction.putValue(Action.SHORT_DESCRIPTION, "Zoom");
		zoomAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_Z);//short cut
		ImageIcon zoomIcon = imageService.getIcon(ImageDefs.ZOOM_ICON_PATH);//lupa
		zoomAction.putValue(Action.LARGE_ICON_KEY, zoomIcon);
		zoomAction.putValue(Action.SMALL_ICON, zoomIcon);

		resetAction = new AbstractAction("Reset") {
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public void actionPerformed(ActionEvent arg0) {
				mandelbrotPanel.reset();
			}
		};
		resetAction.putValue(Action.SHORT_DESCRIPTION, "Reset");
		resetAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
		ImageIcon resetIcon = imageService.getIcon(ImageDefs.RESET_ICON_PATH);
		resetAction.putValue(Action.LARGE_ICON_KEY, resetIcon);
		resetAction.putValue(Action.SMALL_ICON, resetIcon);

		exitAction = new AbstractAction("Exit application") {
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public void actionPerformed(ActionEvent arg0) {
				ApplicationScreen.getInstance().close();
			}
		};
		exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit application");
		exitAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_X);

		aboutAction = new AbstractAction("About") {
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO implement about Screen
			}
		};
		aboutAction.putValue(Action.SHORT_DESCRIPTION, "About");
		aboutAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_P);
		ImageIcon aboutIcon = imageService.getIcon(ImageDefs.ABOUT_ICON_PATH);
		aboutAction.putValue(Action.LARGE_ICON_KEY, aboutIcon);
		aboutAction.putValue(Action.SMALL_ICON, aboutIcon);

	}

	/**
	 * Creates the screen components.
	 */
	private void createComponents() {
		createActionsToolbar();//creeaza toolbarul
		createMandelbrotPanel();//instatiaza mandelbrot panel...iteration, adauga m
	}

	/**
	 * Creates the drawing panel.
	 */
	private void createMandelbrotPanel() {
		mandelbrotPanel = new MandelbrotPanel(iterationNumber);
//		mandelbrotView.setIterationNumber(iterationNumber);
		add((JPanel) mandelbrotPanel, BorderLayout.CENTER);  //adauga mandelbrot panel in mand screen
	}

	/**
	 * {@inheritDoc}
	 */
	public void stateChanged(ChangeEvent e) { //implementeaza changeListener
		JSlider source = (JSlider) e.getSource();  //listener pt slider
		if (!source.getValueIsAdjusting()) {
			iterationNumber = source.getValue();
			mandelbrotPanel.setIterationNumber(iterationNumber); ///lui mandPanel ii setam iteration  number
		}
	}

	/**
	 * Creates the actions tool bar.
	 */
	private void createActionsToolbar() {
		JToolBar actionToolBar = new JToolBar();
		actionToolBar.setFloatable(false);//daca se poate face drag
		actionToolBar.add(zoomAction);//iconuri care apar in toolbar
		actionToolBar.add(resetAction);
		actionToolBar.addSeparator();

		iterationSlider = new JSlider(JSlider.HORIZONTAL, 5, MAX_ITERATION, iterationNumber);//sliderul se adauga in toolbar
		iterationSlider.addChangeListener(this);// face chestia cu state cnage, cand se modfica sliderul se apeleaza state change ////de la 5 la 200 pozitionat la iteration number
		iterationSlider.setToolTipText("Adjust iterations number from 5 to 2000");
		iterationSlider.setPaintTicks(false);
		iterationSlider.setPaintLabels(false);
		iterationSlider.setMaximumSize(new Dimension(975, 30));

		actionToolBar.add(iterationSlider);//

		add(actionToolBar, BorderLayout.PAGE_START);//adauga toolbarul la mand screen la inceput
	}

	/**
	 * Creates the screen menu bar.
	 * 
	 * @return the created menu bar.
	 */
	public JMenuBar createMenuBar() {
		// Create the first menu.
		JMenu actionMenu = new JMenu("Action");
		actionMenu.setMnemonic(KeyEvent.VK_A);//short cut
		actionMenu.add(zoomAction);
		actionMenu.add(resetAction);
		actionMenu.addSeparator();
		actionMenu.add(exitAction);

		JMenu itemMenu = new JMenu("Help");
		itemMenu.setMnemonic(KeyEvent.VK_H);
		itemMenu.add(aboutAction);

		JMenuBar menuBar = new JMenuBar();
		menuBar.add(actionMenu);//creeaza meniurile si se adauga in menu bar
		menuBar.add(itemMenu);

		return menuBar;
	}

}
